/**
 * 淹没分析组件 - 基于mars3d思路的Cesium原生实现
 * 参考mars3d.thing.FloodByGraphic的实现方式
 */
import messageController from '../../../utils/messageController';

const Cesium = window.Cesium;
const turf = window.turf;

class FloodByGraphic {
    constructor(viewer, options = {}) {
        this.viewer = viewer;
        this.options = {
            style: {
                color: "#007be6",
                opacity: 0.5,
                outline: false,
                ...options.style
            },
            perPositionHeight: false, // 是否每个分析点高度都不一样
            ...options
        };
        
        this.isActive = false;
        this.isStart = false;
        this.positions = null;
        this.minHeight = 0;
        this.maxHeight = 100;
        this.speed = 1; // 淹没速度 m/s
        this.currentHeight = 0;
        
        this.floodEntities = [];
        this.elevationGrid = null;
        this.animationId = null;
        
        // 添加更新控制变量
        this.lastUpdateTime = 0;
        this.updateInterval = 1000; // 更新间隔，毫秒（增加到1秒）
        this.pendingHeight = null;
        this.updateTimeoutId = null;
        
        this.eventListeners = {
            start: [],
            change: [],
            end: []
        };
    }
    
    // 事件监听器
    on(eventType, callback) {
        if (this.eventListeners[eventType]) {
            this.eventListeners[eventType].push(callback);
        }
    }
    
    // 触发事件
    fire(eventType, data) {
        if (this.eventListeners[eventType]) {
            this.eventListeners[eventType].forEach(callback => callback(data));
        }
    }
    
    // 设置配置选项
    async setOptions(options) {
        this.options = { ...this.options, ...options };
        
        if (options.positions) {
            this.positions = options.positions;
        }
        if (options.minHeight !== undefined) {
            this.minHeight = options.minHeight;
        }
        if (options.maxHeight !== undefined) {
            this.maxHeight = options.maxHeight;
        }
        if (options.speed !== undefined) {
            this.speed = options.speed;
        }
        
        // 重新计算高程数据
        if (this.positions) {
            console.log('开始计算高程网格...');
            await this.calculateElevationGrid();
            console.log('高程网格计算完成，可以开始分析');
        }
    }
    
    // 计算高程网格数据
    async calculateElevationGrid() {
        if (!this.positions || this.positions.length === 0) return;
        
        console.log('开始计算高程网格数据...');
        
        // 计算区域边界
        const cartographicPositions = this.positions.map(position => {
            if (position instanceof Cesium.Cartesian3) {
                return Cesium.Cartographic.fromCartesian(position);
            }
            return position;
        });
        
        const longitudes = cartographicPositions.map(pos => pos.longitude);
        const latitudes = cartographicPositions.map(pos => pos.latitude);
        const minLon = Math.min(...longitudes);
        const maxLon = Math.max(...longitudes);
        const minLat = Math.min(...latitudes);
        const maxLat = Math.max(...latitudes);
        
        // 创建高程采样网格
        const gridSize = 30; // 网格分辨率
        const elevationGrid = [];
        const elevationPromises = [];
        
        for (let i = 0; i < gridSize; i++) {
            elevationGrid[i] = [];
            for (let j = 0; j < gridSize; j++) {
                const lon = minLon + (maxLon - minLon) * i / (gridSize - 1);
                const lat = minLat + (maxLat - minLat) * j / (gridSize - 1);
                
                // 检查点是否在多边形内
                const point = turf.point([
                    Cesium.Math.toDegrees(lon),
                    Cesium.Math.toDegrees(lat)
                ]);
                
                const polygonCoords = this.positions.map(pos => {
                    if (pos instanceof Cesium.Cartesian3) {
                        const cartographic = Cesium.Cartographic.fromCartesian(pos);
                        return [
                            Cesium.Math.toDegrees(cartographic.longitude),
                            Cesium.Math.toDegrees(cartographic.latitude)
                        ];
                    }
                    return [
                        Cesium.Math.toDegrees(pos.longitude),
                        Cesium.Math.toDegrees(pos.latitude)
                    ];
                });
                
                polygonCoords.push(polygonCoords[0]); // 闭合多边形
                const polygon = turf.polygon([polygonCoords]);
                
                if (turf.booleanPointInPolygon(point, polygon)) {
                    const cartographic = new Cesium.Cartographic(lon, lat);
                    elevationPromises.push(
                        Cesium.sampleTerrainMostDetailed(
                            this.viewer.terrainProvider,
                            [cartographic]
                        ).then(result => {
                            elevationGrid[i][j] = {
                                lon: Cesium.Math.toDegrees(lon),
                                lat: Cesium.Math.toDegrees(lat),
                                height: result[0].height || 0,
                                isValid: true
                            };
                        }).catch(err => {
                            elevationGrid[i][j] = {
                                lon: Cesium.Math.toDegrees(lon),
                                lat: Cesium.Math.toDegrees(lat),
                                height: 0,
                                isValid: false
                            };
                        })
                    );
                } else {
                    elevationGrid[i][j] = {
                        lon: Cesium.Math.toDegrees(lon),
                        lat: Cesium.Math.toDegrees(lat),
                        height: 0,
                        isValid: false
                    };
                }
            }
        }
        
        // 等待所有高程数据计算完成
        await Promise.all(elevationPromises);
        
        // 计算统计信息
        const validCells = elevationGrid.flat().filter(cell => cell.isValid);
        const heights = validCells.map(cell => cell.height);
        
        this.elevationGrid = elevationGrid;
        this.elevationStats = {
            minHeight: Math.min(...heights),
            maxHeight: Math.max(...heights),
            avgHeight: heights.reduce((a, b) => a + b, 0) / heights.length,
            validCells: validCells.length,
            gridSize: gridSize
        };
        
        console.log('高程网格计算完成:', this.elevationStats);
    }
    
    // 开始淹没分析
    start() {
        if (this.isStart) return;
        
        // 清除之前的淹没实体
        this.floodEntities.forEach(entity => {
            this.viewer.entities.remove(entity);
        });
        this.floodEntities = [];
        
        this.isStart = true;
        this.isActive = true;
        this.currentHeight = this.minHeight;
        
        this.fire('start', {
            minHeight: this.minHeight,
            maxHeight: this.maxHeight,
            speed: this.speed
        });
        
        console.log('开始淹没分析动画');
        this.startAnimation();
    }
    
    // 停止淹没分析
    stop() {
        if (!this.isStart) return;
        
        // 清理定时器
        if (this.updateTimeoutId) {
            clearTimeout(this.updateTimeoutId);
            this.updateTimeoutId = null;
        }
        
        this.isStart = false;
        this.isActive = false;
        
        if (this.animationId) {
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
        
        this.fire('end', {
            finalHeight: this.currentHeight
        });
        
        console.log('停止淹没分析动画');
    }
    
    // 设置当前淹没高度
    set height(value) {
        this.currentHeight = value;
        this.pendingHeight = value;
        
        // 触发change事件（用于UI更新）
        this.fire('change', {
            height: this.currentHeight
        });
        
        // 使用延迟更新机制，避免频繁重建实体
        this.scheduleUpdate();
    }
    
    get height() {
        return this.currentHeight;
    }
    
    // 调度更新，避免频繁重建实体
    scheduleUpdate() {
        const now = Date.now();
        
        // 如果距离上次更新时间不足间隔时间，则延迟更新
        if (now - this.lastUpdateTime < this.updateInterval) {
            // 清除之前的定时器
            if (this.updateTimeoutId) {
                clearTimeout(this.updateTimeoutId);
            }
            
            // 设置新的定时器
            this.updateTimeoutId = setTimeout(() => {
                this.performUpdate();
            }, this.updateInterval - (now - this.lastUpdateTime));
        } else {
            // 立即更新
            this.performUpdate();
        }
    }
    
    // 执行实际的更新操作
    performUpdate() {
        this.lastUpdateTime = Date.now();
        
        // 如果高程网格还没有计算完成，先显示基本的淹没效果
        if (!this.elevationGrid || !this.positions) {
            console.log('高程网格未准备好，显示基本淹没效果');
            this.createBasicFloodDisplay();
        } else {
            this.updateFloodDisplay();
        }
        
        console.log('执行淹没效果更新，当前高度:', this.currentHeight);
    }
    
    // 开始动画
    startAnimation() {
        if (!this.isActive) return;
        
        const startTime = Date.now();
        const duration = ((this.maxHeight - this.minHeight) / this.speed) * 1000; // 转换为毫秒
        
        console.log(`开始淹没动画: 从${this.minHeight}m到${this.maxHeight}m, 速度${this.speed}m/s, 预计时长${duration/1000}秒`);
        
        const animate = () => {
            if (!this.isActive) return;
            
            const elapsed = Date.now() - startTime;
            const progress = Math.min(elapsed / duration, 1);
            
            this.currentHeight = this.minHeight + (this.maxHeight - this.minHeight) * progress;
            
            // 触发变化事件（UI更新）
            this.fire('change', {
                height: this.currentHeight,
                progress: progress
            });
            
            // 使用延迟更新机制更新显示
            this.scheduleUpdate();
            
            // 每10帧输出一次调试信息
            if (Math.floor(progress * 100) % 10 === 0) {
                console.log(`淹没进度: ${(progress * 100).toFixed(1)}%, 当前水位: ${this.currentHeight.toFixed(1)}m`);
            }
            
            if (progress < 1) {
                this.animationId = requestAnimationFrame(animate);
            } else {
                this.isStart = false;
                console.log('淹没动画完成');
                this.fire('end', {
                    finalHeight: this.currentHeight
                });
            }
        };
        
        animate();
    }
    
    // 创建基本淹没显示（当高程网格未准备好时）
    createBasicFloodDisplay() {
        if (!this.positions) return;
        
        // 先创建新的淹没实体
        const newFloodEntities = [];
        
        // 使用原始多边形创建基本的淹没区域
        const positions = this.positions.map(pos => {
            if (pos instanceof Cesium.Cartesian3) {
                return pos;
            }
            return Cesium.Cartesian3.fromRadians(pos.longitude, pos.latitude);
        });
        
        // 使用minHeight作为基础高度，currentHeight作为淹没高度
        const baseHeight = this.minHeight || 0;
        const floodHeight = this.currentHeight;
        
        if (floodHeight > baseHeight) {
            const floodEntity = this.viewer.entities.add({
                name: 'BasicFloodArea',
                polygon: {
                    hierarchy: positions,
                    height: baseHeight,
                    extrudedHeight: floodHeight,
                    material: Cesium.Color.fromCssColorString(this.options.style.color)
                        .withAlpha(this.options.style.opacity),
                    outline: this.options.style.outline,
                    outlineColor: Cesium.Color.CYAN,
                    outlineWidth: 2
                }
            });
            
            newFloodEntities.push(floodEntity);
            console.log('创建基本淹没区域:', { baseHeight, floodHeight });
        }
        
        // 添加水位标识
        this.createWaterLevelIndicator(newFloodEntities);
        
        // 新实体创建完成后再清除旧实体，避免闪烁
        // 添加一个小延迟，确保新实体完全渲染到场景中
        setTimeout(() => {
            this.floodEntities.forEach(entity => {
                this.viewer.entities.remove(entity);
            });
            this.floodEntities = newFloodEntities;
            
            // 强制场景重新渲染
            this.viewer.scene.requestRender();
        }, 10); // 10毫秒延迟
    }
    
    // 更新淹没显示
    updateFloodDisplay() {
        console.log('updateFloodDisplay被调用:', {
            hasElevationGrid: !!this.elevationGrid,
            hasPositions: !!this.positions,
            currentHeight: this.currentHeight,
            minHeight: this.minHeight,
            maxHeight: this.maxHeight
        });
        
        if (!this.elevationGrid || !this.positions) {
            console.log('高程网格或位置数据未准备好，使用基本显示');
            this.createBasicFloodDisplay();
            return;
        }
        
        // 计算被淹没的区域
        const floodedCells = this.calculateFloodedCells();
        console.log('计算得到淹没单元格数量:', floodedCells.length);
        
        // 先创建新的淹没实体
        const newFloodEntities = [];
        
        // 创建淹没区域显示（如果有淹没区域）
        if (floodedCells.length > 0) {
            this.createFloodDisplay(floodedCells, newFloodEntities);
        } else {
            // 即使没有淹没区域，也要显示水位标注
            this.createWaterLevelIndicator(newFloodEntities);
        }
        
        // 新实体创建完成后再清除旧实体，避免闪烁
        // 添加一个小延迟，确保新实体完全渲染到场景中
        setTimeout(() => {
            this.floodEntities.forEach(entity => {
                this.viewer.entities.remove(entity);
            });
            this.floodEntities = newFloodEntities;
            
            // 强制场景重新渲染
            this.viewer.scene.requestRender();
            
            console.log('淹没实体更新完成，新实体数量:', this.floodEntities.length);
        }, 10); // 10毫秒延迟
    }
    
    // 计算被淹没的单元格
    calculateFloodedCells() {
        if (!this.elevationGrid) return [];
        
        const floodedCells = [];
        const gridSize = this.elevationStats.gridSize;
        
        console.log('开始计算淹没单元格:', {
            gridSize: gridSize,
            currentHeight: this.currentHeight,
            elevationStats: this.elevationStats
        });
        
        let validCellCount = 0;
        let floodedCellCount = 0;
        
        for (let i = 0; i < gridSize; i++) {
            for (let j = 0; j < gridSize; j++) {
                const cell = this.elevationGrid[i][j];
                if (cell.isValid) {
                    validCellCount++;
                    if (cell.height < this.currentHeight) {
                        floodedCells.push({
                            ...cell,
                            floodDepth: this.currentHeight - cell.height,
                            gridX: i,
                            gridY: j
                        });
                        floodedCellCount++;
                    }
                }
            }
        }
        
        console.log('淹没单元格计算完成:', {
            validCellCount: validCellCount,
            floodedCellCount: floodedCellCount,
            currentHeight: this.currentHeight,
            minElevation: this.elevationStats.minHeight,
            maxElevation: this.elevationStats.maxHeight
        });
        
        return floodedCells;
    }
    
    // 创建淹没区域显示
    createFloodDisplay(floodedCells, entitiesArray = this.floodEntities) {
        console.log('createFloodDisplay被调用:', {
            floodedCellsCount: floodedCells.length,
            renderMode: this.options.style.renderMode,
            currentHeight: this.currentHeight
        });
        
        if (!floodedCells.length) {
            console.log('没有淹没单元格，跳过创建');
            return;
        }
        
        // 方法1：创建整体淹没区域
        if (this.options.style.renderMode === 'unified') {
            console.log('使用统一渲染模式');
            this.createUnifiedFloodArea(floodedCells, entitiesArray);
        } else {
            // 方法2：创建网格化淹没区域
            console.log('使用网格渲染模式');
            this.createGridFloodArea(floodedCells, entitiesArray);
        }
        
        // 添加水位标识
        this.createWaterLevelIndicator(entitiesArray);
        
        console.log('淹没区域创建完成，实体数量:', entitiesArray.length);
    }
    

    
    // 创建统一的淹没区域
    createUnifiedFloodArea(floodedCells, entitiesArray = this.floodEntities) {
        console.log('createUnifiedFloodArea被调用:', {
            positionsCount: this.positions.length,
            minHeight: this.elevationStats.minHeight,
            currentHeight: this.currentHeight,
            color: this.options.style.color,
            opacity: this.options.style.opacity
        });
        
        // 使用原始多边形作为边界
        const positions = this.positions.map(pos => {
            if (pos instanceof Cesium.Cartesian3) {
                return pos;
            }
            return Cesium.Cartesian3.fromRadians(pos.longitude, pos.latitude);
        });
        
        const floodEntity = this.viewer.entities.add({
            name: 'FloodArea',
            polygon: {
                hierarchy: positions,
                height: this.elevationStats.minHeight,
                extrudedHeight: this.currentHeight,
                material: Cesium.Color.fromCssColorString(this.options.style.color)
                    .withAlpha(this.options.style.opacity),
                outline: this.options.style.outline,
                outlineColor: Cesium.Color.CYAN,
                outlineWidth: 2,
                // 确保正确的深度测试
                depthTest: true,
                // 确保实体在地形之上显示
                classificationType: Cesium.ClassificationType.BOTH
            }
        });
        
        entitiesArray.push(floodEntity);
        console.log('统一淹没区域实体已创建:', floodEntity);
    }
    
    // 创建网格化淹没区域
    createGridFloodArea(floodedCells) {
        const gridSize = this.elevationStats.gridSize;
        const cellGroups = this.groupFloodedCells(floodedCells);
        
        cellGroups.forEach((group, index) => {
            if (group.length === 0) return;
            
            const avgDepth = group.reduce((sum, cell) => sum + cell.floodDepth, 0) / group.length;
            const alpha = Math.min(0.3 + (avgDepth / 50) * 0.5, 0.8);
            
            const positions = this.createCellGroupPositions(group, gridSize);
            
            const floodEntity = this.viewer.entities.add({
                name: `FloodArea-${index}`,
                polygon: {
                    hierarchy: positions,
                    height: group[0].height,
                    extrudedHeight: this.currentHeight,
                    material: Cesium.Color.fromCssColorString(this.options.style.color)
                        .withAlpha(alpha),
                    outline: this.options.style.outline,
                    outlineColor: Cesium.Color.LIGHTBLUE,
                    outlineWidth: 1
                }
            });
            
            this.floodEntities.push(floodEntity);
        });
    }
    
    // 将淹没单元格分组
    groupFloodedCells(floodedCells) {
        // 简单分组：按深度范围分组
        const groups = [];
        const depthRanges = [
            { min: 0, max: 1 },
            { min: 1, max: 5 },
            { min: 5, max: 10 },
            { min: 10, max: Infinity }
        ];
        
        depthRanges.forEach(range => {
            const group = floodedCells.filter(cell => 
                cell.floodDepth >= range.min && cell.floodDepth < range.max
            );
            if (group.length > 0) {
                groups.push(group);
            }
        });
        
        return groups;
    }
    
    // 为单元格组创建位置数组
    createCellGroupPositions(group, gridSize) {
        const positions = [];
        
        // 为每个单元格创建一个小矩形
        group.forEach(cell => {
            const cellSize = 0.001; // 网格单元大小
            const lon = cell.lon * Math.PI / 180;
            const lat = cell.lat * Math.PI / 180;
            
            const corners = [
                Cesium.Cartesian3.fromRadians(lon - cellSize/2, lat - cellSize/2),
                Cesium.Cartesian3.fromRadians(lon + cellSize/2, lat - cellSize/2),
                Cesium.Cartesian3.fromRadians(lon + cellSize/2, lat + cellSize/2),
                Cesium.Cartesian3.fromRadians(lon - cellSize/2, lat + cellSize/2)
            ];
            
            positions.push(...corners);
        });
        
        return positions;
    }
    
    // 创建水位标识
    createWaterLevelIndicator(entitiesArray = this.floodEntities) {
        if (!this.positions || this.positions.length === 0) return;
        
        // 计算中心点
        const center = Cesium.BoundingSphere.fromPoints(this.positions).center;
        const cartographic = Cesium.Cartographic.fromCartesian(center);
        
        // 创建水位标注，设置更高的高度确保不被地形遮挡
        const labelEntity = this.viewer.entities.add({
            name: 'WaterLevelIndicator',
            position: Cesium.Cartesian3.fromRadians(
                cartographic.longitude,
                cartographic.latitude,
                this.currentHeight + 200 // 增加高度到200米，确保在地形之上
            ),
            label: {
                text: `水位: ${this.currentHeight.toFixed(1)}m`,
                font: '24px sans-serif', // 大幅增大字体
                fillColor: Cesium.Color.WHITE,
                outlineColor: Cesium.Color.BLACK,
                outlineWidth: 4, // 增加轮廓宽度
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                showBackground: true,
                backgroundColor: Cesium.Color.BLUE.withAlpha(0.9), // 增加背景透明度
                backgroundPadding: new Cesium.Cartesian2(15, 10), // 增加背景内边距
                pixelOffset: new Cesium.Cartesian2(0, -15), // 向上偏移
                heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, // 相对于地面的高度参考
                // 调整距离缩放，确保远近都能看清
                scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 10000, 0.8),
                // 调整透明度变化，远处更透明
                translucencyByDistance: new Cesium.NearFarScalar(1000, 1.0, 10000, 0.9)
            }
        });
        
        entitiesArray.push(labelEntity);
        console.log('水位标注已创建，高度:', this.currentHeight + 200);
    }
    
    // 清除所有淹没显示
    clear() {
        this.floodEntities.forEach(entity => {
            this.viewer.entities.remove(entity);
        });
        this.floodEntities = [];
    }
    
    // 销毁组件
    destroy() {
        this.stop();
        this.clear();
        
        // 清理定时器
        if (this.updateTimeoutId) {
            clearTimeout(this.updateTimeoutId);
            this.updateTimeoutId = null;
        }
        
        this.elevationGrid = null;
        this.positions = null;
        this.eventListeners = { start: [], change: [], end: [] };
    }
}

// 模拟mars3d.PolyUtil.interPolygonByDepth功能
class PolyUtil {
    static async interPolygonByDepth({ scene, positions }) {
        console.log('计算多边形深度信息...');
        
        if (!positions || positions.length === 0) {
            return { minHeight: 0, maxHeight: 100 };
        }
        
        // 转换为地理坐标
        const cartographicPositions = positions.map(position => {
            if (position instanceof Cesium.Cartesian3) {
                return Cesium.Cartographic.fromCartesian(position);
            }
            return position;
        });
        
        // 采样地形高度
        try {
            const sampledPositions = await Cesium.sampleTerrainMostDetailed(
                scene.globe.terrainProvider,
                cartographicPositions
            );
            
            const heights = sampledPositions.map(pos => pos.height || 0);
            const minHeight = Math.min(...heights);
            const maxHeight = Math.max(...heights);
            
            console.log('深度分析结果:', { minHeight, maxHeight });
            
            return {
                minHeight: minHeight - 10, // 留出一些余量
                maxHeight: maxHeight + 10,
                avgHeight: heights.reduce((a, b) => a + b, 0) / heights.length
            };
        } catch (error) {
            console.error('深度分析失败:', error);
            return { minHeight: 0, maxHeight: 100 };
        }
    }
}

// 导出类和工具
export { FloodByGraphic, PolyUtil };

// 默认导出一个便捷的创建函数
export default function createFloodAnalysis(viewer, options = {}) {
    return new FloodByGraphic(viewer, options);
} 